﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Game.Protocol;
using Google.Protobuf;

public delegate void HandleMsgCallback(byte[] buffer);
public  class MsgDispatcher
    {
    private Dictionary<int, HandleMsgCallback>handleMap = new Dictionary<int, HandleMsgCallback>();
    List<HandleMsgCallback> dispatchDelHandle = new List<HandleMsgCallback>();
    /// <summary>
    /// 
    /// </summary>
    /// <param name="type">消息类型</param>
    /// <param name="area">接收的范围</param>
    /// <param name="command">具体的实现</param>
    /// <param name="onHandleMsg"></param>
    public void RegisterByInt(int type,int  area, int command, HandleMsgCallback onHandleMsg)
    {
        int cmdID = (int)(type << 24| area<<16 | command);
        if (!handleMap.ContainsKey(cmdID))
            handleMap[cmdID] = onHandleMsg;
        else
            handleMap[cmdID] += onHandleMsg;
    }
    public void Register(ProtocolType type, ProtocolCommand command, HandleMsgCallback onHandleMsg) {
        this.Register(type, ProtocolArea.ServerToSingleClient, command, onHandleMsg);
    }

    public void Register(ProtocolType type, ProtocolArea area, ProtocolCommand command , HandleMsgCallback onHandleMsg)
    {
        RegisterByInt((int)type, (int)area, (int)command, onHandleMsg);
        //Lua_MsgDispatcher_Register((int)id1, (int)id2, onHandleMsg);
    }

    public void UnregisterByInt(int type, int area,int command,HandleMsgCallback onHandleMsg)
    {
        int cmdID = (int)(type << 24 | area << 16 | command); ;
        if (handleMap.ContainsKey(cmdID))
        {
            handleMap[cmdID] -= onHandleMsg;
            if (handleMap[cmdID] == null)
                handleMap.Remove(cmdID);
            dispatchDelHandle.Add(onHandleMsg);
        }
    }

    public void Unregister(ProtocolType type, ProtocolCommand command, HandleMsgCallback onHandleMsg) {
        Unregister(type, ProtocolArea.ServerToSingleClient, command,onHandleMsg);

    }

    public void Unregister(ProtocolType type, ProtocolArea area, ProtocolCommand command, HandleMsgCallback onHandleMsg)
    {
        UnregisterByInt((int)type, (int)area, (int)command, onHandleMsg);
        //Lua_MsgDispatcher_Register((int)id1, (int)id2, onHandleMsg);
    }

    public void Dispatch(ProtocolType type, ProtocolArea area, ProtocolCommand command, byte[] buffer) {

        Dispatch((int)type, (int)area, (int)command, buffer);

    }

    public void Dispatch(ProtocolType type, ProtocolArea area, ProtocolCommand command, IMessage pbIMessage)
    {

        Dispatch((int)type, (int)area, (int)command, pbIMessage.ToByteArray());

    }


    public void Dispatch(int type, int area,int command, byte[] buffer)
    {
       
        dispatchDelHandle.Clear();
        int cmdID = (int)(type << 24 | area << 16 | command); ;
        HandleMsgCallback handler = null;
        handleMap.TryGetValue(cmdID, out handler);
        if (handler != null)
        {
            Delegate[] list = handler.GetInvocationList();
            for (int i = 0; i < list.Length; ++i)
            {
                Delegate tempDelegate = list[i];
                try
                {
                    HandleMsgCallback callback = tempDelegate as HandleMsgCallback;
                    if (callback != null && !dispatchDelHandle.Contains(callback))
                    {
                        callback(buffer);
                    }
                }
                catch (Exception e)
                {
                    
                    //break;??
                }
            }
            //handler(ms);
        }

        dispatchDelHandle.Clear();
    }
}


